import axios, { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios'
import router from '../router/index.js'
import elHelper from '@/common/elHelper.js'
import { useRequester, useUsers } from '../stores/index'
import comFunc from '../common/comFunc.js'
import { ServerConfig } from '@/common/config.js'

const requesterStore = useRequester()
const userStore = useUsers()
const instance = axios.create()
instance.defaults.timeout = 240000
// axios.defaults.baseURL = process.env.CENTER_API
// axios.defaults.headers.post['content-Type'] = 'application/x-www-form-urlencoded'

// 添加请求拦截器
instance.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    if (userStore.getLoginToken() && config.url) {
      config.headers.set('token', userStore.getLoginToken())
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    if (response.data && response.data.code === 401) {
      elHelper.showErrorMsg('登录超时，请重新登录！')
      router.push('/')
      userStore.logout()
    }
    return response
  },
  function (error) {
    userStore.hadRequestError++
    if (userStore.hadRequestError === 1) {
      if (error.response.status === 401) {
        if (error.response.data.error) {
          if (error.response.data.error.indexOf('TimeOut') >= 0) {
            elHelper.showErrorMsg('登录超时，请重新登录！')
            router.push('/')
            userStore.logout()
          }
        }
      } else if (error.response.status === 403) {
        elHelper.showErrorMsg('该账号没有本功能的操作权限，请联系管理员设置')
        router.go(-1)
      }
    }
    return Promise.reject(error)
  }
)
function encryptData(data: any) {
  if (requesterStore.isHttpEncrypt) {
    const nonce_str = comFunc.getNonceStr(null)
    const content_key = comFunc.encryptAES(nonce_str, requesterStore.shareKey)
    const content = {
      data: comFunc.encryptAES(data, content_key),
      nonce_str: nonce_str
    }
    return {
      data: comFunc.encryptAES(content, requesterStore.shareKey)
    }
  } else {
    return data
  }
}
function decryptData(data: string) {
  if (requesterStore.isHttpEncrypt) {
    const content = JSON.parse(comFunc.decryptAES(data, requesterStore.shareKey))
    if (content && content.data && content.nonce_str) {
      const nonce_str = content.nonce_str
      const content_key = comFunc.encryptAES(nonce_str, requesterStore.shareKey)
      const rtn = comFunc.decryptAES(content.data, content_key)
      if (rtn.startsWith('{')) {
        return JSON.parse(rtn)
      } else if (rtn.startsWith('[')) {
        return JSON.parse(rtn)
      } else {
        return rtn
      }
    } else {
      return null
    }
  } else {
    return data
  }
}
// 注：接口的基础地址主要分为：业务地址（ServerConfig.CENTER_API）和流程地址（ServerConfig.WORKFLOW_API）
// 其中：
// -----1、业务地址对应的api，均为传统的 post/patch/$delete/get 方法
// -----2、基础流程对应的api，均为传统的 basicWFPost/basicWFPatch/basicWFDelete/basicWFGet 方法
// -----3、流程执行对应的api，目前只有一个 workflowPost方法（请求头ApplicationToken，ApplicationCode）

// post方法
export function post(url: string, data = {}, header = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.CENTER_API + url,
      method: 'post',
      data: encryptData(data),
      headers: header
    })
      .then((response) => {
        if (requesterStore.isHttpEncrypt) {
          const re: any = {}
          Object.assign(re, response)
          if (re.data.result) {
            re.data.result = decryptData(re.data.result.data)
          } else {
            re.data = decryptData(re.data.data)
          }
          resolve(re)
        } else {
          resolve(response)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}

export function upload(
  url: string,
  file: any,
  onProgress?: (percentage: number) => void
): Promise<any> {
  const formData = new FormData()
  formData.append('file', file)
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.CENTER_API + url,
      method: 'post',
      headers: {
        'Content-Type': 'multipart/form-databoundary = ' + new Date().getTime()
      },
      data: formData,
      onUploadProgress: (progressEvent: any) => {
        const currentPer = Math.round((progressEvent.loaded * 100) / progressEvent.total)
        const currentPercentage = currentPer > 100 ? 100 : currentPer
        if (onProgress) onProgress(currentPercentage)
      }
    })
      .then((response) => {
        if (requesterStore.isHttpEncrypt) {
          const re: any = {}
          Object.assign(re, response)
          if (re.data.result) {
            re.data.result = decryptData(re.data.result.data)
          } else {
            re.data = decryptData(re.data.data)
          }
          resolve(re)
        } else {
          resolve(response)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// 流程部分的post方法
export function basicWFPost(url: string, data = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.WORKFLOW_API + url,
      method: 'post',
      data
    })
      .then((response) => {
        resolve(response)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// 流程图中的post方法（主要用在流程执行的excute的方法，以及流程执行中选人）
export function workflowPost(url: string, data = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    axios({
      url: ServerConfig.WORKFLOW_API + url,
      method: 'post',
      data,
      headers: {
        ApplicationToken: ServerConfig.ApplicationToken,
        ApplicationCode: ServerConfig.ApplicationCode
      }
    })
      .then((response) => {
        resolve(response)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// get方法
export function get(url: any, params = {}, header = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.CENTER_API + url,
      method: 'get',
      params,
      headers: header
    })
      .then((response) => {
        if (url === '/_init') {
          resolve(response)
        } else {
          if (requesterStore.isHttpEncrypt) {
            const re: any = {}
            Object.assign(re, response)
            if (re.data.result) {
              re.data.result = decryptData(re.data.result.data)
            } else {
              re.data = decryptData(re.data.data)
            }
            resolve(re)
          } else {
            resolve(response)
          }
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}
/**
 * 文件下载
 * @param path
 * @param header
 * @returns
 */
export const getFile = async (path: string, header = {}): Promise<any> => {
  const re = await instance({
    url: ServerConfig.CENTER_API + path,
    method: 'get',
    headers: header
  }).catch((error) => {
    console.error(error)
  })
  return re
}

// 流程部分的get方法
export function basicWFGet(url: string, params = {}) {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.WORKFLOW_API + url,
      method: 'get',
      params
    })
      .then((response) => {
        resolve(response)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// delete方法
export function $delete(url: string, params: any = {}): Promise<any> {
  let p: any = {}
  if (params.data) {
    p.data = encryptData(params.data)
  } else {
    p = params
  }
  return new Promise((resolve, reject) => {
    instance
      .delete(ServerConfig.CENTER_API + url, p)
      .then((response) => {
        if (requesterStore.isHttpEncrypt) {
          const re: any = {}
          Object.assign(re, response)
          if (re.data.result) {
            re.data.result = decryptData(re.data.result.data)
          } else {
            re.data = decryptData(re.data.data)
          }
          resolve(re)
        } else {
          resolve(response)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// 流程部分的delete方法
export function basicWFDelete(url: string, params: any): Promise<any> {
  return new Promise((resolve, reject) => {
    instance
      .delete(ServerConfig.WORKFLOW_API + url, params)
      .then((response) => {
        resolve(response)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// patch方法
export function patch(url: string, data = {}, header = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.CENTER_API + url,
      method: 'patch',
      data: encryptData(data),
      headers: header
    })
      .then((response) => {
        if (requesterStore.isHttpEncrypt) {
          const re: any = {}
          Object.assign(re, response)
          if (re.data.result) {
            re.data.result = decryptData(re.data.result.data)
          } else {
            re.data = decryptData(re.data.data)
          }
          resolve(re)
        } else {
          resolve(response)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// 流程部分的patch方法
export function basicWFPatch(url: string, data = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: ServerConfig.WORKFLOW_API + url,
      method: 'patch',
      data
    })
      .then((response) => {
        resolve(response)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

// 当执行事件采用的是http形式时(暂未使用)
export function httpAxios(url: string, method: string, data: object, params: any): Promise<any> {
  return new Promise((resolve, reject) => {
    instance({
      url: url,
      method: method,
      data: encryptData(data),
      params: params
    })
      .then((response) => {
        if (requesterStore.isHttpEncrypt) {
          const re: any = {}
          Object.assign(re, response)
          if (re.data.result) {
            re.data.result = decryptData(re.data.result.data)
          } else {
            re.data = decryptData(re.data.data)
          }
          resolve(re)
        } else {
          resolve(response)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}
export { instance }
